// Copyright by Scot Drysdale

package cn.edu.nju.software.grapheditor.shape;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
/**@author smy*/
//Completed on May 21th
//Modified on May 28th
public class Segment extends Shape {
    private int x1;
    private int x2;
    private int y1;
    private int y2;
    private int centerx;
    private int centery;
	public Segment(Color c,int x1,int x2,int y1,int y2) {
		super(c);
		this.x1=x1;
		this.x2=x2;
		this.y1=y1;
		this.y2=y2;
		this.centerx=(int)((x2+x1)/2);
		this.centery=(int)((y2+y1)/2);
	}

	/**
	 * Helper method that returns true if Point p is within a tolerance of given
	 * bounding box. Here, the bounding box is given by the coordinates of its
	 * left, top, right, and bottom.
	 */
	private static boolean almostContainsPoint(Point p, int left, int top,
			int right, int bottom, double tolerance) {
		return p.x >= left - tolerance && p.y >= top - tolerance
				&& p.x <= right + tolerance && p.y <= bottom + tolerance;
	}

	// Helper method that returns the distance from Point p to the line
	// containing a line segment whose endpoints are given.
	private static double distanceToPoint(Point p, int x1, int y1, int x2,
			int y2) {
		if (x1 == x2) // vertical segment?
			return (double) (Math.abs(p.x - x1)); // yes, use horizontal
		// distance
		else if (y1 == y2) // horizontal segment?
			return (double) (Math.abs(p.y - y1)); // yes, use vertical distance
		else {
			// Here, we know that the segment is neither vertical nor
			// horizontal.
			// Compute m, the slope of the line containing the segment.
			double m = ((double) (y1 - y2)) / ((double) (x1 - x2));

			// Compute mperp, the slope of the line perpendicular to the
			// segment.
			double mperp = -1.0 / m;

			// Compute the (x, y) intersection of the line containing the
			// segment and the line that is perpendicular to the segment and
			// that
			// contains Point p.
			double x = (((double) y1) - ((double) p.y) - (m * x1) + (mperp * p.x))
					/ (mperp - m);
			double y = m * (x - x1) + y1;

			// Return the distance between Point p and (x, y).
			return Math.sqrt(Math.pow(p.x - x, 2) + Math.pow(p.y - y, 2));
		}
	}

	@Override
	public boolean containsPoint(Point p) {
		if(x1==x2 || y1==y2)return Segment.almostContainsPoint(p, x1, y1, x2, y2, 3);
		else if(Segment.distanceToPoint(p, x1, y1, x2, y2)<=3)return true;
		else return false;
	}

	@Override
	public void drawShape(Graphics page) {
		page.drawLine(x1, y1, x2, y2);
	}

	@Override
	public Point getCenter() {
		Point ans=new Point();
		ans.x=this.centerx;
		ans.y=this.centery;
		return ans;
	}

	@Override
	public void move(int deltaX, int deltaY) {
		this.x1+=deltaX;
		this.x2+=deltaX;
		this.y1+=deltaY;
		this.y2+=deltaY;
		this.centerx=(int)((x2+x1)/2);
		this.centery=(int)((y2+y1)/2);
	}

	@Override
	public String getclass() {
		return "Segment";
	}
	
	public int[] getargs(){
		int[] ans=new int[4];
		ans[0]=this.x1;
		ans[1]=this.x2;
		ans[2]=this.y1;
		ans[3]=this.y2;
		return ans;
	}
}
